-
-
Notifications
You must be signed in to change notification settings - Fork 968
Query improvements #2905
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Query improvements #2905
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/webapp/app/components/runs/v3/SharedFilters.tsx (1)
19-33: Remove unused imports.
useRef(line 19),SpanPresenter(line 32), anduseLocation(line 33) are imported but not used in this file. These should be removed to avoid confusion.🧹 Suggested fix
-import { startTransition, useCallback, useEffect, useRef, useState, type ReactNode } from "react"; +import { startTransition, useCallback, useEffect, useState, type ReactNode } from "react";import { ShortcutDefinition } from "~/hooks/useShortcutKeys"; -import { SpanPresenter } from "~/presenters/v3/SpanPresenter.server"; -import { useLocation } from "@remix-run/react";
🤖 Fix all issues with AI agents
In
`@apps/webapp/app/routes/_app.orgs`.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx:
- Around line 507-520: handleTimeFilterChange currently updates URL search
params via replaceSearchParams (AITimeFilter) but QueryEditorForm never reads
those params or auto-submits, so AI updates don't apply; fix by wiring
QueryEditorForm to react to search param changes: either have QueryEditorForm
read the period/from/to params from the URL (useSearchParams) and trigger its
submit handler when they change, or change the parent to pass the AITimeFilter
values as props to QueryEditorForm and call its onSubmit programmatically when
handleTimeFilterChange runs; update references: handleTimeFilterChange,
replaceSearchParams, QueryEditorForm, and any submit handler (e.g., onSubmit or
submitQuery) to ensure form re-submission occurs after the params update.
- Around line 366-368: The time filter state variables period, from and to are
never initialized from or synchronized with URL search params, so changes made
by handleTimeFilterChange update the URL but not the component state (and
refresh loses the values); fix by reading search params (e.g., via
useSearchParams or equivalent) on mount and whenever params change and
initializing/setting period, setPeriod, from, setFrom, to, setTo accordingly,
and ensure handleTimeFilterChange also updates these state setters (or
alternatively lift the time filter state to the parent and pass it down so the
URL and form stay in sync).
♻️ Duplicate comments (2)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (1)
370-372: Regex fortriggered_atdetection has known limitations.The regex can match
triggered_atappearing in string literals or comments, which could incorrectly disable the time filter UI. This was noted in a previous review.apps/webapp/app/components/code/TSQLResultsTable.tsx (1)
63-66: Remove the stray doc comment abovegetFormattedValue.
It references the fuzzy filter but sits before the formatter docs, which is confusing.Suggested change
-/** - * Fuzzy filter function using match-sorter ranking - */
🧹 Nitpick comments (7)
apps/webapp/app/components/runs/v3/SharedFilters.tsx (4)
274-279: Usetypeinstead ofinterface.Per coding guidelines, prefer type aliases over interfaces in TypeScript.
♻️ Suggested fix
-/** Values passed to onApply callback when a time filter is applied */ -export interface TimeFilterApplyValues { - period?: string; - from?: string; - to?: string; -} +/** Values passed to onApply callback when a time filter is applied */ +export type TimeFilterApplyValues = { + period?: string; + from?: string; + to?: string; +};
281-291: Usetypeinstead ofinterface.Same as above—per coding guidelines, prefer type aliases.
♻️ Suggested fix
-export interface TimeFilterProps { +export type TimeFilterProps = { defaultPeriod?: string; period?: string; from?: string; to?: string; /** Label name used in the filter display, defaults to "Created" */ labelName?: string; applyShortcut?: ShortcutDefinition | undefined; /** Callback when the user applies a time filter selection, receives the applied values */ onValueChange?: (values: TimeFilterApplyValues) => void; -} +};
416-496: Consider clarifying callback semantics.The relationship between
onApplyandonValueChangemay be confusing to consumers:
onValueChangeis checked first to determine controlled vs URL modeonApplyfires unconditionally after either pathIf both callbacks are provided, both will be invoked. Consider documenting this behavior or consolidating to a single callback to reduce ambiguity.
827-831: Simplify with nullish coalescing.Minor readability improvement using
??instead of a ternary.♻️ Suggested fix
- shortcut={applyShortcut ? applyShortcut : { + shortcut={applyShortcut ?? { modifiers: ["mod"], key: "Enter", enabledOnInputElements: true, }}apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (1)
757-774: Consider adding error handling for clipboard operations.The
navigator.clipboard.writeTextcalls can fail if clipboard permissions are denied. While not critical, adding a try-catch with user feedback would improve UX.♻️ Suggested improvement
const handleCopyCSV = () => { const csv = rowsToCSV(rows, columns); - navigator.clipboard.writeText(csv); - setIsOpen(false); + navigator.clipboard.writeText(csv) + .then(() => setIsOpen(false)) + .catch((err) => console.error("Failed to copy:", err)); };apps/webapp/app/components/code/TSQLResultsTable.tsx (2)
217-221: Prefer a type alias forColumnMeta.
This aligns with the project’s TS style guidance.As per coding guidelines, prefer `type` over `interface` in TS.Suggested change
-interface ColumnMeta { - outputColumn: OutputColumnMetadata; - alignment: "left" | "right"; -} +type ColumnMeta = { + outputColumn: OutputColumnMetadata; + alignment: "left" | "right"; +};
699-758: Use a button for the copy affordance (keyboard access).
The clickable<span>isn’t focusable; a<button>improves accessibility without changing layout.Suggested change
- <span + <button + type="button" + aria-label="Copy cell value" onClick={(e) => { e.stopPropagation(); e.preventDefault(); copy(); }} - className="absolute right-1 top-1/2 z-10 flex -translate-y-1/2 cursor-pointer" + className="absolute right-1 top-1/2 z-10 flex -translate-y-1/2 cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500/50" > <SimpleTooltip button={ <span className={cn( "flex size-6 items-center justify-center rounded border border-charcoal-650 bg-charcoal-750", copied ? "text-green-500" : "text-text-dimmed hover:border-charcoal-600 hover:bg-charcoal-700 hover:text-text-bright" )} > {copied ? ( <ClipboardCheckIcon className="size-3.5" /> ) : ( <ClipboardIcon className="size-3.5" /> )} </span> } content={copied ? "Copied!" : "Copy"} disableHoverableContent /> - </span> + </button>
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/webapp/app/components/code/TSQLResultsTable.tsxapps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead
**/*.{ts,tsx}: Always import tasks from@trigger.dev/sdk, never use@trigger.dev/sdk/v3or deprecatedclient.defineJobpattern
Every Trigger.dev task must be exported and have a uniqueidproperty with no timeouts in the run function
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use zod for validation in packages/core and apps/webapp
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function declarations instead of default exports
Import from
@trigger.dev/coreusing subpaths only, never import from root
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsx
apps/webapp/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access all environment variables through the
envexport ofenv.server.tsinstead of directly accessingprocess.envin the Trigger.dev webapp
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsx
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
apps/webapp/**/*.{ts,tsx}: When importing from@trigger.dev/corein the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webappAccess environment variables via
envexport fromapps/webapp/app/env.server.ts, never useprocess.envdirectly
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsx
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}
📄 CodeRabbit inference engine (AGENTS.md)
Format code using Prettier before committing
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsx
🧠 Learnings (2)
📚 Learning: 2025-12-08T15:19:56.823Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 2760
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx:278-281
Timestamp: 2025-12-08T15:19:56.823Z
Learning: In apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx, the tableState search parameter uses intentional double-encoding: the parameter value contains a URL-encoded URLSearchParams string, so decodeURIComponent(value("tableState") ?? "") is required to fully decode it before parsing with new URLSearchParams(). This pattern allows bundling multiple filter/pagination params as a single search parameter.
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to internal-packages/database/**/*.{ts,tsx} : Use Prisma for database interactions in internal-packages/database with PostgreSQL
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🧬 Code graph analysis (2)
apps/webapp/app/components/runs/v3/SharedFilters.tsx (2)
apps/webapp/app/hooks/useShortcutKeys.tsx (1)
ShortcutDefinition(14-19)apps/webapp/app/components/runs/v3/RunFilters.tsx (1)
filterIcon(227-263)
apps/webapp/app/components/code/TSQLResultsTable.tsx (7)
internal-packages/tsql/src/query/schema.ts (2)
column(318-330)OutputColumnMetadata(242-257)internal-packages/clickhouse/src/index.ts (1)
OutputColumnMetadata(61-61)packages/core/src/v3/index.ts (1)
formatDurationMilliseconds(36-36)apps/webapp/app/utils/numberFormatter.ts (2)
formatCurrencyAccurate(48-50)formatNumber(15-22)apps/webapp/app/components/environments/EnvironmentLabel.tsx (1)
EnvironmentSlug(141-143)apps/webapp/app/hooks/useCopy.ts (1)
useCopy(3-22)apps/webapp/app/utils/cn.ts (1)
cn(77-79)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
- GitHub Check: typecheck / typecheck
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (19)
apps/webapp/app/components/runs/v3/SharedFilters.tsx (2)
141-206: LGTM!The
labelNameparameterization is cleanly threaded through the function, allowing customizable labels while maintaining backward compatibility with the default value.
293-340: LGTM!The component cleanly supports both controlled mode (via props) and URL-driven mode (via
useSearchParams). OnlyonValueChangeis passed down, avoiding the double-calling issue mentioned in past reviews.apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (7)
1-70: LGTM!Imports are well-organized and appropriately scoped.
72-104: LGTM!The access control logic properly handles admin/impersonation bypass and feature flag validation.
112-155: LGTM!The loader properly validates access, handles missing resources with 404s, and returns the expected data shape.
157-166: LGTM!The schema correctly uses zod for validation with nullable/optional time filter fields.
255-277: Time filter fallback logic is well-structured.The handling of different time filter combinations (between, gte, lte, period-based) is comprehensive. The
parse-durationlibrary returnsnullfor invalid inputs, so the?? 7 * 24 * 60 * 60 * 1000fallback correctly handles malformed period strings.
560-714: LGTM!The results display logic properly handles all states (loading, error, explain, data) with appropriate conditional rendering and user-friendly error recovery.
804-823: LGTM!The ScopeItem component cleanly handles all scope types with appropriate labels.
apps/webapp/app/components/code/TSQLResultsTable.tsx (10)
1-61: Import set + sizing constants look solid.
Clear TanStack integration and well-named sizing constants make the later layout logic easy to follow.
70-187: Formatting + fuzzy filter logic is well-aligned.
Combining raw and formatted values is a nice touch for search relevance.
189-215: Debounced input implementation looks good.
State sync + timeout cleanup are handled cleanly.
223-332: Column width heuristics are clear and bounded.
Sampling + min/max constraints should keep sizing stable.
390-403: Right-alignment helper is straightforward.
Nice centralized rule for numeric-like columns.
666-675: EnvironmentSlug swap looks correct.
Keeps display consistent with the updated label component.
677-697: JSON cell truncation/tooltip handling looks good.
Clear and consistent with other truncation patterns.
764-843: Header cell UX (tooltip/sort/filter) looks solid.
Good separation of concerns and readable interactions.
848-884: Filter row wiring is clean.
Focus handling and debounced updates are well-implemented.
886-1183: Virtualized table integration looks solid.
Row model + virtualizer hookup is clean and should scale well.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
.../app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
Outdated
Show resolved
Hide resolved
.../app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/webapp/app/components/primitives/DateTime.tsx (1)
104-123: Update callers offormatDateTimethat are missing theincludeDateparameter.The
includeDateparameter is now required (no default value). At least two locations need updating:
apps/webapp/app/v3/services/bulk/BulkActionV2.server.tslines 339-340: Calls with only 5 arguments (missingincludeDate)apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsxline 574: Call with only 5 arguments (missingincludeDate)These calls will fail at runtime without providing the required 6th parameter.
🤖 Fix all issues with AI agents
In `@apps/webapp/app/components/runs/v3/SharedFilters.tsx`:
- Around line 248-257: The same-day check in the "range" case of
SharedFilters.tsx currently uses from.getDate() === to.getDate(), which falsely
treats different months/years as the same day; replace this with a proper
full-date comparison by importing and using isSameDay from date-fns to compute
the isSameDay boolean, then keep the DateTime rendering logic (DateTime
date={from!} ... and DateTime date={to!} includeDate={!isSameDay} ...) so the
`to` label only hides the date when the two timestamps are truly the same
calendar day.
♻️ Duplicate comments (3)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.ts (1)
1-19: Guard against NaN/precision loss in stats parsing.Non‑numeric stat values will propagate
NaNinto the UI (e.g.,"NaN rows read"). Consider finite checks with a safe fallback.🛠️ Suggested hardening
- const readRows = parseInt(stats.read_rows, 10); - const readBytes = parseInt(stats.read_bytes, 10); - const elapsedNs = parseInt(stats.elapsed_ns, 10); - const byteSeconds = parseFloat(stats.byte_seconds); + const readRows = Number(stats.read_rows); + const readBytes = Number(stats.read_bytes); + const elapsedNs = Number(stats.elapsed_ns); + const byteSeconds = Number(stats.byte_seconds); + + if (![readRows, readBytes, elapsedNs, byteSeconds].every(Number.isFinite)) { + return "—"; + }apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (2)
387-390: Regex-basedtriggered_atdetection still matches literals/comments.
542-552: Ensure AI time‑filter updates propagate to form state and execution.After
replaceSearchParams, confirm the editor picks upperiod/from/toand re-submits (or otherwise applies the new bounds), or the AI-suggested time filter won’t take effect until manual submit.
🧹 Nitpick comments (5)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.ts (1)
22-31: Consider extending units beyond GB for large datasets.For TB+ values, the formatter caps at GB and produces large GB numbers, which is harder to read. Extending units improves UX.
♻️ Example adjustment
- const sizes = ["B", "KB", "MB", "GB"]; + const sizes = ["B", "KB", "MB", "GB", "TB", "PB"];apps/webapp/app/components/code/AIQueryInput.tsx (1)
33-43: Prefer atypealias instead of aninterfacefor props.Repository guidelines ask for
typein TS/TSX.
As per coding guidelines, please consider the change below.♻️ Proposed change
-interface AIQueryInputProps { +type AIQueryInputProps = { onQueryGenerated: (query: string) => void; /** Called when the AI sets a time filter - updates URL search params */ onTimeFilterChange?: (filter: AITimeFilter) => void; /** Set this to a prompt to auto-populate and immediately submit */ autoSubmitPrompt?: string; /** Change this to force re-submission even if prompt is the same */ autoSubmitKey?: number; /** Get the current query in the editor (used for edit mode) */ getCurrentQuery?: () => string; -} +};apps/webapp/app/components/runs/v3/SharedFilters.tsx (1)
279-296: Prefertypealiases overinterfacein TSX here.Project guidelines call for
typealiases in.tsxfiles.As per coding guidelines, prefer `type` aliases here.♻️ Proposed refactor
-export interface TimeFilterApplyValues { +export type TimeFilterApplyValues = { period?: string; from?: string; to?: string; -} +}; -export interface TimeFilterProps { +export type TimeFilterProps = { defaultPeriod?: string; period?: string; from?: string; to?: string; /** Label name used in the filter display, defaults to "Created" */ labelName?: string; applyShortcut?: ShortcutDefinition | undefined; /** Callback when the user applies a time filter selection, receives the applied values */ onValueChange?: (values: TimeFilterApplyValues) => void; -} +};apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (1)
358-363: Use a type alias instead of an interface forQueryEditorFormHandle.♻️ Suggested change
-interface QueryEditorFormHandle { - setQuery: (query: string) => void; - setScope: (scope: QueryScope) => void; - getQuery: () => string; - setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => void; -} +type QueryEditorFormHandle = { + setQuery: (query: string) => void; + setScope: (scope: QueryScope) => void; + getQuery: () => string; + setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => void; +};As per coding guidelines, prefer type aliases over interfaces.
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsx (1)
8-46: Prefer matching multi‑word SQL keywords before single‑word ones.This avoids highlighting only the
JOINportion ofLEFT JOIN,RIGHT JOIN, etc.♻️ Suggested tweak
- const keywordPattern = new RegExp( - `\\b(${SQL_KEYWORDS.map((k) => k.replace(/\s+/g, "\\s+")).join("|")})\\b`, - "gi" - ); + const keywordPattern = new RegExp( + `\\b(${[...SQL_KEYWORDS] + .sort((a, b) => b.length - a.length) + .map((k) => k.replace(/\s+/g, "\\s+")) + .join("|")})\\b`, + "gi" + );
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
apps/webapp/app/components/code/AIQueryInput.tsxapps/webapp/app/components/primitives/DateTime.tsxapps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/presenters/v3/QueryPresenter.server.tsapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.tsapps/webapp/app/services/queryService.server.tsinternal-packages/database/prisma/migrations/20260120115732_add_time_filter_to_customer_query/migration.sqlinternal-packages/database/prisma/schema.prisma
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/webapp/app/services/queryService.server.ts
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead
**/*.{ts,tsx}: Always import tasks from@trigger.dev/sdk, never use@trigger.dev/sdk/v3or deprecatedclient.defineJobpattern
Every Trigger.dev task must be exported and have a uniqueidproperty with no timeouts in the run function
Files:
apps/webapp/app/presenters/v3/QueryPresenter.server.tsapps/webapp/app/components/primitives/DateTime.tsxapps/webapp/app/components/code/AIQueryInput.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.tsapps/webapp/app/components/runs/v3/SharedFilters.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use zod for validation in packages/core and apps/webapp
Files:
apps/webapp/app/presenters/v3/QueryPresenter.server.tsapps/webapp/app/components/primitives/DateTime.tsxapps/webapp/app/components/code/AIQueryInput.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.tsapps/webapp/app/components/runs/v3/SharedFilters.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function declarations instead of default exports
Import from
@trigger.dev/coreusing subpaths only, never import from root
Files:
apps/webapp/app/presenters/v3/QueryPresenter.server.tsapps/webapp/app/components/primitives/DateTime.tsxapps/webapp/app/components/code/AIQueryInput.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.tsapps/webapp/app/components/runs/v3/SharedFilters.tsx
apps/webapp/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access all environment variables through the
envexport ofenv.server.tsinstead of directly accessingprocess.envin the Trigger.dev webapp
Files:
apps/webapp/app/presenters/v3/QueryPresenter.server.tsapps/webapp/app/components/primitives/DateTime.tsxapps/webapp/app/components/code/AIQueryInput.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.tsapps/webapp/app/components/runs/v3/SharedFilters.tsx
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
apps/webapp/**/*.{ts,tsx}: When importing from@trigger.dev/corein the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webappAccess environment variables via
envexport fromapps/webapp/app/env.server.ts, never useprocess.envdirectly
Files:
apps/webapp/app/presenters/v3/QueryPresenter.server.tsapps/webapp/app/components/primitives/DateTime.tsxapps/webapp/app/components/code/AIQueryInput.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.tsapps/webapp/app/components/runs/v3/SharedFilters.tsx
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)
**/*.ts: When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs
Do not use high-cardinality attributes in OTEL metrics such as UUIDs/IDs (envId, userId, runId, projectId, organizationId), unbounded integers (itemCount, batchSize, retryCount), timestamps (createdAt, startTime), or free-form strings (errorMessage, taskName, queueName)
When exporting OTEL metrics via OTLP to Prometheus, be aware that the exporter automatically adds unit suffixes to metric names (e.g., 'my_duration_ms' becomes 'my_duration_ms_milliseconds', 'my_counter' becomes 'my_counter_total'). Account for these transformations when writing Grafana dashboards or Prometheus queries
Files:
apps/webapp/app/presenters/v3/QueryPresenter.server.tsapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.ts
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}
📄 CodeRabbit inference engine (AGENTS.md)
Format code using Prettier before committing
Files:
apps/webapp/app/presenters/v3/QueryPresenter.server.tsapps/webapp/app/components/primitives/DateTime.tsxapps/webapp/app/components/code/AIQueryInput.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.tsapps/webapp/app/components/runs/v3/SharedFilters.tsx
internal-packages/database/prisma/migrations/**/*.sql
📄 CodeRabbit inference engine (CLAUDE.md)
internal-packages/database/prisma/migrations/**/*.sql: When editing the Prisma schema, remove extraneous migration lines related to specific tables:_BackgroundWorkerToBackgroundWorkerFile,_BackgroundWorkerToTaskQueue,_TaskRunToTaskRunTag,_WaitpointRunConnections,_completedWaitpoints,SecretStore_key_idx, and unrelatedTaskRunindexes
Database indexes must use CONCURRENTLY to avoid table locks and must be in their own separate migration file
Files:
internal-packages/database/prisma/migrations/20260120115732_add_time_filter_to_customer_query/migration.sql
🧠 Learnings (6)
📚 Learning: 2026-01-15T11:50:06.044Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.044Z
Learning: Applies to internal-packages/database/prisma/migrations/**/*.sql : When editing the Prisma schema, remove extraneous migration lines related to specific tables: `_BackgroundWorkerToBackgroundWorkerFile`, `_BackgroundWorkerToTaskQueue`, `_TaskRunToTaskRunTag`, `_WaitpointRunConnections`, `_completedWaitpoints`, `SecretStore_key_idx`, and unrelated `TaskRun` indexes
Applied to files:
internal-packages/database/prisma/schema.prismainternal-packages/database/prisma/migrations/20260120115732_add_time_filter_to_customer_query/migration.sql
📚 Learning: 2025-12-08T15:19:56.823Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 2760
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx:278-281
Timestamp: 2025-12-08T15:19:56.823Z
Learning: In apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx, the tableState search parameter uses intentional double-encoding: the parameter value contains a URL-encoded URLSearchParams string, so decodeURIComponent(value("tableState") ?? "") is required to fully decode it before parsing with new URLSearchParams(). This pattern allows bundling multiple filter/pagination params as a single search parameter.
Applied to files:
apps/webapp/app/components/code/AIQueryInput.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.ts
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to internal-packages/database/**/*.{ts,tsx} : Use Prisma for database interactions in internal-packages/database with PostgreSQL
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
📚 Learning: 2026-01-08T15:57:09.323Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/otel-metrics.mdc:0-0
Timestamp: 2026-01-08T15:57:09.323Z
Learning: Applies to **/*.ts : Do not use high-cardinality attributes in OTEL metrics such as UUIDs/IDs (envId, userId, runId, projectId, organizationId), unbounded integers (itemCount, batchSize, retryCount), timestamps (createdAt, startTime), or free-form strings (errorMessage, taskName, queueName)
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.ts
📚 Learning: 2026-01-08T15:57:09.323Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/otel-metrics.mdc:0-0
Timestamp: 2026-01-08T15:57:09.323Z
Learning: Applies to **/*.ts : When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.ts
📚 Learning: 2026-01-15T11:50:06.044Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.044Z
Learning: Applies to internal-packages/database/prisma/migrations/**/*.sql : Database indexes must use CONCURRENTLY to avoid table locks and must be in their own separate migration file
Applied to files:
internal-packages/database/prisma/migrations/20260120115732_add_time_filter_to_customer_query/migration.sql
🧬 Code graph analysis (2)
apps/webapp/app/components/code/AIQueryInput.tsx (1)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/types.ts (1)
AITimeFilter(5-9)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsx (4)
apps/webapp/app/presenters/v3/QueryPresenter.server.ts (1)
QueryHistoryItem(5-15)apps/webapp/app/components/primitives/Buttons.tsx (1)
Button(296-329)apps/webapp/app/assets/icons/ClockRotateLeftIcon.tsx (1)
ClockRotateLeftIcon(1-15)apps/webapp/app/components/runs/v3/SharedFilters.tsx (1)
timeFilterRenderValues(208-277)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: typecheck / typecheck
🔇 Additional comments (23)
internal-packages/database/prisma/schema.prisma (1)
2472-2478: LGTM!The new time-filter fields (
filterPeriod,filterFrom,filterTo) are correctly defined as optional (String?,DateTime?) since time filters are not always applied. The field placement and documentation comments are appropriate.internal-packages/database/prisma/migrations/20260120115732_add_time_filter_to_customer_query/migration.sql (1)
1-5: LGTM!The migration is clean and focused, adding only the three new nullable columns. Since this only adds nullable columns without default values, it's a non-blocking DDL operation safe for production tables. No extraneous migration lines present. Based on learnings, the CONCURRENTLY guideline only applies to index creation, which is not applicable here.
apps/webapp/app/presenters/v3/QueryPresenter.server.ts (2)
5-15: LGTM!The
QueryHistoryItemtype correctly extends with the new time-filter fields. Usingtypeinstead ofinterfacefollows the coding guidelines. The nullable types (string | null,Date | null) correctly correspond to the optional Prisma fields (String?,DateTime?).
28-30: LGTM!The select projection and mapping correctly include the new time-filter fields. Direct pass-through is appropriate since Prisma handles the
DateTimeto JavaScriptDateconversion automatically.Also applies to: 46-48
apps/webapp/app/components/code/AIQueryInput.tsx (2)
21-29: Time-filter wiring looks solid.Immediate application on
time_filterplus the result fallback makes the flow resilient if an event is missed.Also applies to: 45-48, 182-207, 219-219
389-392: Status copy updates read well.apps/webapp/app/components/primitives/DateTime.tsx (4)
1-40: LGTM!The import cleanup and SSR-compatible timezone handling with
useSyncExternalStoreare well-implemented. The caching strategy for the local timezone is efficient.
55-102: LGTM - Good SSR hydration fix.The
suppressHydrationWarningwrapper is the correct approach for date/time content that may render differently between server (UTC) and client (local timezone). The newincludeDateprop is backward-compatible with its default value oftrue.
168-336: LGTM - Consistent hydration fix across components.The
suppressHydrationWarningpattern is consistently applied toSmartDateTime,DateTimeAccurateInner, andDateTimeShortcomponents, ensuring SSR compatibility across the entire date/time rendering surface.
399-436: LGTM!The tooltip content correctly passes
includeDate: trueexplicitly to allformatDateTimecalls, ensuring tooltips always display the complete date information regardless of the parent component'sincludeDatesetting.apps/webapp/app/components/runs/v3/SharedFilters.tsx (4)
141-205: Label-aware time filter rendering looks good.Nice propagation of
labelNameinto the computed filter display.
298-342: TimeFilter controlled props wiring looks solid.Nice integration of
labelNameandonValueChangewith existing URL-based defaults.
421-501: Controlled vs URL mode branching reads clean.The apply path is easy to follow, and the state resets are consistent.
867-870: Good guard on numeric timestamps.Restricting numeric parsing to fully numeric strings prevents accidental timestamp parsing of ISO values.
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (8)
1-71: No concerns with the updated imports.
72-78: Helper keeps Date/string normalization straightforward.
263-301: Confirm fallback doesn’t double‑filter when SQL already includestriggered_at.The UI disables the time filter when the query already filters
triggered_at, but the action always passeswhereClauseFallback. Please verifyexecuteQueryignores this fallback in that case, or add a server-side guard to skip it to avoid unexpected extra filtering.
475-491: Good: TimeFilter changes sync state before fetcher submit.
617-707: Results header + table card layout look solid.
721-743: Chart/config split layout is clean and contained.
821-823: Popover trigger swap looks fine.
845-855: Environment label rendering reads well in the scope list.apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsx (1)
79-138: History popover UX and selection flow look good.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@apps/webapp/app/components/primitives/AppliedFilter.tsx`:
- Around line 54-56: In AppliedFilter.tsx, the JSX condition currently uses
"label !== undefined" which still renders the colon when label is null or empty;
change the conditional around the label block (the JSX that renders <div
className="text-text-bright"><span>{label}</span>:) to use a truthy check (e.g.,
"if (label)" or "Boolean(label)") so the whole label block is omitted for
null/empty/other falsy values — update the conditional in the component's
render/return where "label !== undefined" is used.
♻️ Duplicate comments (4)
apps/webapp/app/components/runs/v3/SharedFilters.tsx (2)
247-257: Fix same-day detection to avoid hiding dates across months/years.Using
getDate()alone compares only the day-of-month (1-31), so Jan 5 and Feb 5 would incorrectly be treated as the same day, omitting the date in thetolabel.🐛 Proposed fix
case "range": { - //If the day is the same, only show the time for the `to` date - const isSameDay = from && to && from.getDate() === to.getDate(); + //If the day is the same, only show the time for the `to` date + const sameDay = from && to && isSameDay(from, to); valueLabel = ( <span> <DateTime date={from!} includeTime includeSeconds /> –{" "} - <DateTime date={to!} includeTime includeSeconds includeDate={!isSameDay} /> + <DateTime date={to!} includeTime includeSeconds includeDate={!sameDay} /> </span> ); }
3-17: MissingisSameDayimport from date-fns.The same-day comparison at line 249 uses
from.getDate() === to.getDate(), which only compares the day-of-month and will incorrectly treat dates like Jan 5 and Feb 5 as the same day. ImportisSameDayfrom date-fns.🐛 Proposed fix
import { endOfDay, endOfMonth, endOfWeek, + isSameDay, isSaturday, isSunday, previousSaturday, startOfDay, startOfMonth, startOfWeek, startOfYear, subDays, subMonths, subWeeks, } from "date-fns";apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (2)
387-389: Regex may mis-detecttriggered_atinside strings/comments.This is the same limitation noted previously; it can disable the UI even when
triggered_atis only in a literal.
543-556: AI time-filter updates only the URL, not the editor state.
handleTimeFilterChangedoesn’t use the newsetTimeFilter, so AI-selected ranges won’t show up in the TimeFilter UI or affect the next submit unless the user manually changes it.🐛 Minimal fix (sync UI state)
const handleTimeFilterChange = useCallback( (filter: AITimeFilter) => { replaceSearchParams({ period: filter.period, from: filter.from, to: filter.to, cursor: undefined, direction: undefined, }); + editorRef.current?.setTimeFilter(filter); }, [replaceSearchParams] );
🧹 Nitpick comments (2)
apps/webapp/app/components/runs/v3/SharedFilters.tsx (1)
277-295: Prefertypeoverinterfaceper coding guidelines.The coding guidelines specify using types instead of interfaces for TypeScript definitions.
♻️ Proposed refactor
-/** Values passed to onApply callback when a time filter is applied */ -export interface TimeFilterApplyValues { - period?: string; - from?: string; - to?: string; -} +/** Values passed to onApply callback when a time filter is applied */ +export type TimeFilterApplyValues = { + period?: string; + from?: string; + to?: string; +}; -export interface TimeFilterProps { +export type TimeFilterProps = { defaultPeriod?: string; period?: string; from?: string; to?: string; /** Label name used in the filter display, defaults to "Created" */ labelName?: string; hideLabel?: boolean; applyShortcut?: ShortcutDefinition | undefined; /** Callback when the user applies a time filter selection, receives the applied values */ onValueChange?: (values: TimeFilterApplyValues) => void; -} +};apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (1)
357-363: Prefer a type alias over an interface here.This file is TS-only and the project guideline is to use
typealiases.As per coding guidelines, prefer `type` over `interface` in TS files.♻️ Suggested refactor
-interface QueryEditorFormHandle { - setQuery: (query: string) => void; - setScope: (scope: QueryScope) => void; - getQuery: () => string; - setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => void; -} +type QueryEditorFormHandle = { + setQuery: (query: string) => void; + setScope: (scope: QueryScope) => void; + getQuery: () => string; + setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => void; +};
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/webapp/app/components/primitives/AppliedFilter.tsxapps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead
**/*.{ts,tsx}: Always import tasks from@trigger.dev/sdk, never use@trigger.dev/sdk/v3or deprecatedclient.defineJobpattern
Every Trigger.dev task must be exported and have a uniqueidproperty with no timeouts in the run function
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/primitives/AppliedFilter.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use zod for validation in packages/core and apps/webapp
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/primitives/AppliedFilter.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function declarations instead of default exports
Import from
@trigger.dev/coreusing subpaths only, never import from root
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/primitives/AppliedFilter.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
apps/webapp/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access all environment variables through the
envexport ofenv.server.tsinstead of directly accessingprocess.envin the Trigger.dev webapp
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/primitives/AppliedFilter.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
apps/webapp/**/*.{ts,tsx}: When importing from@trigger.dev/corein the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webappAccess environment variables via
envexport fromapps/webapp/app/env.server.ts, never useprocess.envdirectly
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/primitives/AppliedFilter.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}
📄 CodeRabbit inference engine (AGENTS.md)
Format code using Prettier before committing
Files:
apps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/primitives/AppliedFilter.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🧠 Learnings (2)
📚 Learning: 2025-12-08T15:19:56.823Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 2760
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx:278-281
Timestamp: 2025-12-08T15:19:56.823Z
Learning: In apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx, the tableState search parameter uses intentional double-encoding: the parameter value contains a URL-encoded URLSearchParams string, so decodeURIComponent(value("tableState") ?? "") is required to fully decode it before parsing with new URLSearchParams(). This pattern allows bundling multiple filter/pagination params as a single search parameter.
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to internal-packages/database/**/*.{ts,tsx} : Use Prisma for database interactions in internal-packages/database with PostgreSQL
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🧬 Code graph analysis (3)
apps/webapp/app/components/runs/v3/SharedFilters.tsx (3)
apps/webapp/app/components/primitives/DateTime.tsx (1)
DateTime(55-102)apps/webapp/app/hooks/useShortcutKeys.tsx (1)
ShortcutDefinition(14-19)apps/webapp/app/hooks/useSearchParam.ts (1)
useSearchParams(7-64)
apps/webapp/app/components/primitives/AppliedFilter.tsx (1)
apps/webapp/app/utils/cn.ts (1)
cn(77-79)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (14)
apps/webapp/app/components/runs/v3/SharedFilters.tsx (2)
timeFilters(139-204)TimeFilter(297-346)internal-packages/clickhouse/src/index.ts (1)
WhereClauseFallback(59-59)internal-packages/clickhouse/src/client/tsql.ts (1)
WhereClauseFallback(28-28)apps/webapp/app/presenters/v3/QueryPresenter.server.ts (1)
QueryHistoryItem(5-15)apps/webapp/app/v3/querySchemas.ts (1)
defaultQuery(430-433)apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsx (1)
QueryHistoryPopover(79-139)apps/webapp/app/components/primitives/Tooltip.tsx (1)
SimpleTooltip(141-141)apps/webapp/app/routes/runs.$runParam.ts (1)
loader(12-68)apps/webapp/app/hooks/useSearchParam.ts (1)
useSearchParams(7-64)apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/types.ts (1)
AITimeFilter(5-9)apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.ts (1)
formatQueryStats(1-20)apps/webapp/app/components/code/TSQLResultsTable.tsx (1)
TSQLResultsTable(886-1184)apps/webapp/app/components/code/ChartConfigPanel.tsx (1)
ChartConfigPanel(80-522)apps/webapp/app/components/environments/EnvironmentLabel.tsx (1)
EnvironmentLabel(78-139)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
🔇 Additional comments (15)
apps/webapp/app/components/primitives/AppliedFilter.tsx (2)
22-30: LGTM on the type definition.Making
labeloptional is a clean approach to support the use case of showing filters without a label.
51-51: Good use of conditional spacing.The dynamic gap adjustment based on label presence maintains proper visual alignment.
apps/webapp/app/components/runs/v3/SharedFilters.tsx (5)
139-204: LGTM!The
labelNameparameter is properly integrated with a sensible default, and all branches correctly propagate it totimeFilterRenderValues.
297-346: LGTM!The controlled mode integration is clean - prop values correctly override URL params, and only
onValueChangeis passed toTimeDropdown, avoiding the previously flagged double-apply issue.
421-501: LGTM!The controlled mode implementation is well-structured:
onValueChangeskips URL navigation for controlled consumersonApplyserves as a post-apply callback for both modes (useful for analytics/side effects)- Dependency array is complete
830-844: LGTM!The shortcut customization with a sensible default (mod+Enter) is a good UX pattern.
864-873: LGTM!The refined logic correctly distinguishes between numeric timestamps and date strings. The regex approach prevents ISO date strings from being incorrectly parsed as timestamps.
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (8)
1-70: No review needed for the import adjustments.
72-78: Helper for Date/string normalization looks good.
165-174: Action schema now accepts time-filter inputs—nice.
258-312: Time-filter fallback + history wiring looks solid.
429-493: Time-filter hidden inputs + auto-submit are well wired.
583-749: Results/graph layout refactor looks good.
822-824: Popover trigger change is fine.
846-856: Environment label usage is clear and consistent.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/webapp/app/components/code/QueryResultsChart.tsx (1)
538-551: Avoid padding when filling time gaps.
timeDomainincludes padding for axis rendering; using it forfillTimeGapsadds artificial zero buckets at the edges, which can misrepresent the series (e.g., lines dropping to zero outside the real data range). Use the raw min/max timestamps for gap filling and keep padding only for the axis domain.🛠️ Suggested fix
- if (isDateBased && timeDomain) { - const timestamps = dateValues.map((d) => d.getTime()); - const dataInterval = detectDataInterval(timestamps); - data = fillTimeGaps( - data, - xDataKey, - yAxisColumns, - timeDomain[0], - timeDomain[1], - dataInterval, - granularity, - aggregation - ); - } + if (isDateBased && timeDomain) { + const timestamps = dateValues.map((d) => d.getTime()); + const dataInterval = detectDataInterval(timestamps); + const minTime = Math.min(...timestamps); + const maxTime = Math.max(...timestamps); + data = fillTimeGaps( + data, + xDataKey, + yAxisColumns, + minTime, + maxTime, + dataInterval, + granularity, + aggregation + ); + } @@ - if (isDateBased && timeDomain) { - const timestamps = dateValues.map((d) => d.getTime()); - const dataInterval = detectDataInterval(timestamps); - data = fillTimeGaps( - data, - xDataKey, - series, - timeDomain[0], - timeDomain[1], - dataInterval, - granularity, - aggregation - ); - } + if (isDateBased && timeDomain) { + const timestamps = dateValues.map((d) => d.getTime()); + const dataInterval = detectDataInterval(timestamps); + const minTime = Math.min(...timestamps); + const maxTime = Math.max(...timestamps); + data = fillTimeGaps( + data, + xDataKey, + series, + minTime, + maxTime, + dataInterval, + granularity, + aggregation + ); + }Also applies to: 607-620
🤖 Fix all issues with AI agents
In `@apps/webapp/app/components/primitives/charts/ChartBar.tsx`:
- Around line 187-195: The conditional rendering for the ReferenceArea is using
truthy checks (enableZoom && zoom?.refAreaLeft && zoom?.refAreaRight) which
prevents zero-valued bounds from rendering; change the condition in ChartBar.tsx
to use nullish checks so 0 is allowed (e.g., check enableZoom and that
zoom.refAreaLeft and zoom.refAreaRight are not null/undefined via != null or !==
null/undefined). Apply the same fix to the other similar block that renders
inspection lines/zoom (the second ReferenceArea rendering block later in the
file using zoom?.refAreaLeft/Right).
♻️ Duplicate comments (2)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (2)
389-391: Regex can still false-positive on string literals/comments.The raw query regex will match
triggered_atinside quoted strings or comments. Consider stripping SQL literals/comments before testing.
545-557: AI time-filter updates don’t reach the form state/submission.
handleTimeFilterChangeonly updates URL search params; the form’s hidden inputs stay stale, so the query results don’t reflect the AI-selected range until a manual change/submit. Please sync the editor state and re-submit.✅ Suggested fix
const handleTimeFilterChange = useCallback( (filter: AITimeFilter) => { + editorRef.current?.setTimeFilter({ + period: filter.period, + from: filter.from, + to: filter.to, + }); + editorRef.current?.submit?.(); replaceSearchParams({ period: filter.period, from: filter.from, to: filter.to, // Clear cursor/direction when time filter changes cursor: undefined, direction: undefined, }); }, [replaceSearchParams] );Also add a submit method on the handle to let the parent trigger a submit after state updates:
-type QueryEditorFormHandle = { +type QueryEditorFormHandle = { setQuery: (query: string) => void; setScope: (scope: QueryScope) => void; getQuery: () => string; setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => void; + submit: () => void; };useImperativeHandle( ref, () => ({ setQuery, setScope, getQuery: () => query, setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => { - setPeriod(filter.period); - setFrom(filter.from); - setTo(filter.to); + flushSync(() => { + setPeriod(filter.period); + setFrom(filter.from); + setTo(filter.to); + }); }, + submit: () => { + if (formRef.current) { + fetcher.submit(formRef.current); + } + }, }), [query] );
🧹 Nitpick comments (2)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (1)
360-365: Prefer atypealias forQueryEditorFormHandle.This file is TSX and the guideline requires
typeoverinterface. Please convert to a type alias. As per coding guidelines.♻️ Proposed change
-interface QueryEditorFormHandle { - setQuery: (query: string) => void; - setScope: (scope: QueryScope) => void; - getQuery: () => string; - setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => void; -} +type QueryEditorFormHandle = { + setQuery: (query: string) => void; + setScope: (scope: QueryScope) => void; + getQuery: () => string; + setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => void; +};apps/webapp/app/components/code/QueryResultsChart.tsx (1)
26-33: Prefer a type alias for props.Use a
typealias instead of aninterfaceforQueryResultsChartPropsto match the codebase TS guideline.As per coding guidelines, use types over interfaces.♻️ Suggested refactor
-interface QueryResultsChartProps { +type QueryResultsChartProps = { rows: Record<string, unknown>[]; columns: OutputColumnMetadata[]; config: ChartConfiguration; fullLegend?: boolean; /** Callback when "View all" legend button is clicked */ onViewAllLegendItems?: () => void; -} +};
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
apps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/components/primitives/Dialog.tsxapps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/components/primitives/charts/ChartContext.tsxapps/webapp/app/components/primitives/charts/ChartLegendCompound.tsxapps/webapp/app/components/primitives/charts/ChartLine.tsxapps/webapp/app/components/primitives/charts/ChartRoot.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/webapp/app/components/primitives/charts/ChartRoot.tsx
- apps/webapp/app/components/primitives/charts/ChartContext.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead
**/*.{ts,tsx}: Always import tasks from@trigger.dev/sdk, never use@trigger.dev/sdk/v3or deprecatedclient.defineJobpattern
Every Trigger.dev task must be exported and have a uniqueidproperty with no timeouts in the run function
Files:
apps/webapp/app/components/primitives/charts/ChartLegendCompound.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/components/primitives/charts/ChartLine.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/primitives/Dialog.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use zod for validation in packages/core and apps/webapp
Files:
apps/webapp/app/components/primitives/charts/ChartLegendCompound.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/components/primitives/charts/ChartLine.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/primitives/Dialog.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function declarations instead of default exports
Import from
@trigger.dev/coreusing subpaths only, never import from root
Files:
apps/webapp/app/components/primitives/charts/ChartLegendCompound.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/components/primitives/charts/ChartLine.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/primitives/Dialog.tsx
apps/webapp/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access all environment variables through the
envexport ofenv.server.tsinstead of directly accessingprocess.envin the Trigger.dev webapp
Files:
apps/webapp/app/components/primitives/charts/ChartLegendCompound.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/components/primitives/charts/ChartLine.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/primitives/Dialog.tsx
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
apps/webapp/**/*.{ts,tsx}: When importing from@trigger.dev/corein the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webappAccess environment variables via
envexport fromapps/webapp/app/env.server.ts, never useprocess.envdirectly
Files:
apps/webapp/app/components/primitives/charts/ChartLegendCompound.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/components/primitives/charts/ChartLine.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/primitives/Dialog.tsx
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}
📄 CodeRabbit inference engine (AGENTS.md)
Format code using Prettier before committing
Files:
apps/webapp/app/components/primitives/charts/ChartLegendCompound.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/components/primitives/charts/ChartLine.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsxapps/webapp/app/components/primitives/Dialog.tsx
🧠 Learnings (2)
📚 Learning: 2025-12-08T15:19:56.823Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 2760
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx:278-281
Timestamp: 2025-12-08T15:19:56.823Z
Learning: In apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx, the tableState search parameter uses intentional double-encoding: the parameter value contains a URL-encoded URLSearchParams string, so decodeURIComponent(value("tableState") ?? "") is required to fully decode it before parsing with new URLSearchParams(). This pattern allows bundling multiple filter/pagination params as a single search parameter.
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to internal-packages/database/**/*.{ts,tsx} : Use Prisma for database interactions in internal-packages/database with PostgreSQL
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🧬 Code graph analysis (5)
apps/webapp/app/components/primitives/charts/ChartLegendCompound.tsx (6)
apps/webapp/app/components/primitives/charts/ChartCompound.tsx (4)
ChartLegendCompoundProps(77-77)ChartLegendCompound(101-101)useChartContext(104-104)useSeriesTotal(105-105)apps/webapp/app/components/primitives/charts/ChartContext.tsx (1)
useChartContext(43-49)apps/webapp/app/components/primitives/charts/ChartRoot.tsx (1)
useSeriesTotal(177-190)apps/webapp/app/utils/cn.ts (1)
cn(77-79)apps/webapp/app/components/primitives/AnimatedNumber.tsx (1)
AnimatedNumber(4-16)apps/webapp/app/components/primitives/Paragraph.tsx (1)
Paragraph(88-107)
apps/webapp/app/components/code/QueryResultsChart.tsx (1)
apps/webapp/app/components/primitives/charts/ChartCompound.tsx (1)
Chart(92-98)
apps/webapp/app/components/primitives/charts/ChartBar.tsx (6)
apps/webapp/app/components/primitives/charts/ChartCompound.tsx (6)
ChartBarRendererProps(75-75)ChartBarRenderer(101-101)useChartContext(104-104)useHasNoData(105-105)useZoomHandlers(106-106)ZoomTooltip(106-106)apps/webapp/app/components/primitives/charts/ChartContext.tsx (1)
useChartContext(43-49)apps/webapp/app/components/primitives/charts/ChartRoot.tsx (1)
useHasNoData(158-171)apps/webapp/app/components/primitives/charts/ChartZoom.tsx (2)
useZoomHandlers(173-244)ZoomTooltip(105-167)apps/webapp/app/components/primitives/charts/Chart.tsx (2)
ChartTooltip(450-450)ChartTooltipContent(451-451)apps/webapp/app/components/primitives/charts/hooks/useHighlightState.ts (1)
getBarOpacity(95-115)
apps/webapp/app/components/primitives/charts/ChartLine.tsx (5)
apps/webapp/app/components/primitives/charts/ChartCompound.tsx (4)
ChartLineRendererProps(76-76)ChartLineRenderer(101-101)useChartContext(104-104)useHasNoData(105-105)apps/webapp/app/components/primitives/charts/ChartContext.tsx (1)
useChartContext(43-49)apps/webapp/app/components/primitives/charts/ChartRoot.tsx (1)
useHasNoData(158-171)apps/webapp/app/components/primitives/charts/ChartLoading.tsx (3)
ChartLineLoading(63-73)ChartLineNoData(75-94)ChartLineInvalid(96-115)apps/webapp/app/components/primitives/charts/Chart.tsx (2)
ChartTooltip(450-450)ChartTooltipContent(451-451)
apps/webapp/app/components/primitives/Dialog.tsx (1)
apps/webapp/app/utils/cn.ts (1)
cn(77-79)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: typecheck / typecheck
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
apps/webapp/app/components/primitives/Dialog.tsx (4)
13-19: DialogPortal wrapper looks good.
Nice encapsulation of the portal container styling.
22-35: DialogOverlay export + styling is solid.
Clear, reusable overlay with consistent animation utilities.
37-52: Fullscreen prop wiring is correct.
Conditional class split is clean and keeps the non-fullscreen behavior intact.
116-125: Export updates are consistent.
Public API now exposes the new primitives as expected.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@apps/webapp/app/components/code/QueryResultsChart.tsx`:
- Around line 815-844: The y-axis domain currently hardcodes [0, "auto"] which
clips negative values; update the logic that builds yAxisProps in
QueryResultsChart.tsx to compute a dynamic lower bound (e.g., min(0,
actualMinValue) or "auto" when no data) instead of always 0, using the available
series/data/aggregations used to render the chart (refer to yAxisProps), so
negative sums/avgs/mins are shown while keeping the axis anchored at zero when
all values are non‑negative.
In
`@apps/webapp/app/routes/_app.orgs`.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx:
- Around line 265-287: timeFilters currently favors period and can ignore
explicit from/to when both are supplied in the URL; to ensure explicit ranges
always win, derive the period argument passed into timeFilters as undefined
whenever from or to are present (e.g., compute const effectivePeriod = (from ||
to) ? undefined : period and call timeFilters({ period: effectivePeriod, from,
to, defaultPeriod: DEFAULT_PERIOD })); then continue using the returned
timeFilter and existing triggeredAtFallback logic (refs: timeFilters,
timeFilter, triggeredAtFallback, DEFAULT_PERIOD, parse).
♻️ Duplicate comments (3)
apps/webapp/app/components/primitives/charts/ChartRoot.tsx (1)
193-206: Totals should be scoped to series keys only.The current implementation sums every numeric property except
dataKey, which could include non-series metadata fields (e.g., timestamps, IDs). This would inflate totals incorrectly.🐛 Proposed fix
export function useSeriesTotal(): Record<string, number> { - const { data, dataKey } = useChartContext(); + const { data, dataKeys } = useChartContext(); return useMemo(() => { - return data.reduce((acc, item) => { - Object.entries(item).forEach(([key, value]) => { - if (key !== dataKey) { - acc[key] = (acc[key] || 0) + (Number(value) || 0); - } - }); + return data.reduce((acc, item) => { + dataKeys.forEach((key) => { + const value = item[key]; + acc[key] = (acc[key] || 0) + (Number(value) || 0); + }); return acc; }, {} as Record<string, number>); - }, [data, dataKey]); + }, [data, dataKeys]); }apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (2)
389-392: triggered_at detection can still match strings/comments.The regex can match
triggered_atinside literals/comments, disabling the time filter incorrectly. Consider stripping SQL literals/comments before testing.
545-557: AI time-filter updates don’t flow into the editor state/submit.
handleTimeFilterChangeonly updates URL params; the editor’speriod/from/tostate and submission remain unchanged. Consider callingeditorRef.current?.setTimeFilter(filter)and triggering a submit (e.g., expose a submit method or lift time filter state).
🧹 Nitpick comments (3)
apps/webapp/app/components/primitives/charts/ChartRoot.tsx (1)
9-37: Consider stronger typing fordataprop.Using
any[]fordatareduces type safety. A generic type parameter or a record type would provide better compile-time checks.💡 Suggested improvement
-export type ChartRootProps = { +export type ChartRootProps<T extends Record<string, unknown> = Record<string, unknown>> = { config: ChartConfig; - data: any[]; + data: T[]; dataKey: string;apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (1)
359-365: Prefer a type alias over an interface for QueryEditorFormHandle.This file is TS/TSX; repo guidelines prefer
typehere.
As per coding guidelines, ...♻️ Suggested update
-interface QueryEditorFormHandle { +type QueryEditorFormHandle = { setQuery: (query: string) => void; setScope: (scope: QueryScope) => void; getQuery: () => string; setTimeFilter: (filter: { period?: string; from?: string; to?: string }) => void; -} +};apps/webapp/app/components/code/QueryResultsChart.tsx (1)
26-33: Prefer atypealias for props.As per coding guidelines, prefer `type` over `interface` for TS props.♻️ Suggested refactor
-interface QueryResultsChartProps { +type QueryResultsChartProps = { rows: Record<string, unknown>[]; columns: OutputColumnMetadata[]; config: ChartConfiguration; fullLegend?: boolean; /** Callback when "View all" legend button is clicked */ onViewAllLegendItems?: () => void; -} +};
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/components/primitives/charts/ChartRoot.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead
**/*.{ts,tsx}: Always import tasks from@trigger.dev/sdk, never use@trigger.dev/sdk/v3or deprecatedclient.defineJobpattern
Every Trigger.dev task must be exported and have a uniqueidproperty with no timeouts in the run function
Files:
apps/webapp/app/components/primitives/charts/ChartRoot.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use zod for validation in packages/core and apps/webapp
Files:
apps/webapp/app/components/primitives/charts/ChartRoot.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function declarations instead of default exports
Import from
@trigger.dev/coreusing subpaths only, never import from root
Files:
apps/webapp/app/components/primitives/charts/ChartRoot.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
apps/webapp/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access all environment variables through the
envexport ofenv.server.tsinstead of directly accessingprocess.envin the Trigger.dev webapp
Files:
apps/webapp/app/components/primitives/charts/ChartRoot.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
apps/webapp/**/*.{ts,tsx}: When importing from@trigger.dev/corein the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webappAccess environment variables via
envexport fromapps/webapp/app/env.server.ts, never useprocess.envdirectly
Files:
apps/webapp/app/components/primitives/charts/ChartRoot.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}
📄 CodeRabbit inference engine (AGENTS.md)
Format code using Prettier before committing
Files:
apps/webapp/app/components/primitives/charts/ChartRoot.tsxapps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🧠 Learnings (2)
📚 Learning: 2025-12-08T15:19:56.823Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 2760
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx:278-281
Timestamp: 2025-12-08T15:19:56.823Z
Learning: In apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx, the tableState search parameter uses intentional double-encoding: the parameter value contains a URL-encoded URLSearchParams string, so decodeURIComponent(value("tableState") ?? "") is required to fully decode it before parsing with new URLSearchParams(). This pattern allows bundling multiple filter/pagination params as a single search parameter.
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to internal-packages/database/**/*.{ts,tsx} : Use Prisma for database interactions in internal-packages/database with PostgreSQL
Applied to files:
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🧬 Code graph analysis (3)
apps/webapp/app/components/primitives/charts/ChartRoot.tsx (5)
apps/webapp/app/components/primitives/charts/ChartContext.tsx (3)
LabelFormatter(11-11)ChartProvider(69-107)useChartContext(43-49)apps/webapp/app/components/primitives/charts/hooks/useZoomSelection.ts (1)
ZoomRange(3-6)apps/webapp/app/utils/cn.ts (1)
cn(77-79)apps/webapp/app/components/primitives/charts/Chart.tsx (1)
ChartContainer(449-449)apps/webapp/app/components/primitives/charts/ChartLegendCompound.tsx (1)
ChartLegendCompound(34-204)
apps/webapp/app/components/code/QueryResultsChart.tsx (1)
apps/webapp/app/components/primitives/charts/ChartCompound.tsx (1)
Chart(92-98)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (6)
apps/webapp/app/components/runs/v3/SharedFilters.tsx (2)
timeFilters(139-204)TimeFilter(297-346)apps/webapp/app/presenters/v3/QueryPresenter.server.ts (1)
QueryHistoryItem(5-15)apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsx (1)
QueryHistoryPopover(79-139)apps/webapp/app/components/primitives/Tooltip.tsx (1)
SimpleTooltip(141-141)apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/types.ts (1)
AITimeFilter(5-9)apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/utils.ts (1)
formatQueryStats(1-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (22)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: typecheck / typecheck
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (7)
apps/webapp/app/components/primitives/charts/ChartRoot.tsx (4)
1-7: LGTM!Imports are well-organized and appropriately scoped.
60-103: LGTM!Clean compound component composition. Props are correctly distributed between
ChartProviderandChartRootInner, and the JSDoc examples clearly illustrate usage patterns.
116-167: LGTM!Layout logic correctly handles both fill-container and fixed-height scenarios. The conditional zoom styling and legend placement outside the chart container are well-implemented.
174-187: LGTM!The hook correctly identifies empty data states while treating zero values as valid data. The logic properly iterates over
dataKeysto check all series.apps/webapp/app/components/code/QueryResultsChart.tsx (3)
3-4: ChartCompound import wiring looks good.
780-792: Legend label formatting for date-based axes looks solid.
699-705: Prop plumbing intoChart.Rootand conditional legend behavior look consistent.Also applies to: 846-893
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
.../app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@apps/webapp/app/components/code/QueryResultsChart.tsx`:
- Around line 841-852: Move the useMemo hook that computes yAxisDomain so it
runs unconditionally before any early returns: relocate the yAxisDomain =
useMemo(...) block to just after legendLabelFormatter and before the
validation/early return checks in the component so all hooks (including useMemo
for yAxisDomain) are called at the top level and in the same order on every
render.
In `@apps/webapp/app/routes/storybook.charts/route.tsx`:
- Around line 49-57: The handleZoomChange function currently only logs the
ZoomRange and leaves dateRange?.setDateRange commented out, so zooms don't
propagate; update handleZoomChange to call dateRange?.setDateRange(range.start,
range.end) (converting range.start/end to the expected types if necessary) so
the shared DateRangeContext is updated and other components (header, charts)
sync; reference the handleZoomChange function and dateRange?.setDateRange to
locate where to wire this.
♻️ Duplicate comments (1)
apps/webapp/app/components/primitives/charts/ChartBar.tsx (1)
258-269: Allow zero-valued inspection line to render.The truthy check
zoom?.inspectionLine &&will skip rendering when the value is0, which can happen with numeric x-axes. Use a nullish check instead.Suggested fix
- {enableZoom && zoom?.inspectionLine && ( + {enableZoom && zoom?.inspectionLine != null && (
🧹 Nitpick comments (9)
apps/webapp/app/components/primitives/charts/ChartBar.tsx (2)
14-21: Remove unused imports.
cn,ChartConfig, andChartStateare imported but not used in this file.Suggested fix
import { ChartTooltip, ChartTooltipContent, - type ChartConfig, - type ChartState, } from "~/components/primitives/charts/Chart"; -import { cn } from "~/utils/cn"; import { ChartBarLoading, ChartBarInvalid, ChartBarNoData } from "./ChartLoading";
187-195: Nullish check could be improved for robustness.The condition uses
!== nullwhich doesn't guard againstundefined. Ifzoomexists butrefAreaLeftisundefined, the conditionundefined !== nullevaluates totrue, potentially passing invalid values toReferenceArea.Suggested fix
- {enableZoom && zoom?.refAreaLeft !== null && zoom?.refAreaRight !== null && ( + {enableZoom && zoom?.refAreaLeft != null && zoom?.refAreaRight != null && (apps/webapp/app/components/code/TSQLResultsTable.tsx (2)
159-166: Consider making undefined values searchable.Undefined values render as "UNDEFINED" in the UI but the fuzzy filter treats them as empty strings, so searching for "undefined" won't find these cells. For consistency with null handling (which correctly uses "NULL" for both display and search):
Suggested fix
const rawValue = cellValue === null ? "NULL" : cellValue === undefined - ? "" + ? "UNDEFINED" : typeof cellValue === "object" ? JSON.stringify(cellValue) : String(cellValue);
214-218: Prefer type over interface per coding guidelines.Suggested fix
-// Extended column meta to store OutputColumnMetadata -interface ColumnMeta { - outputColumn: OutputColumnMetadata; - alignment: "left" | "right"; -} +// Extended column meta to store OutputColumnMetadata +type ColumnMeta = { + outputColumn: OutputColumnMetadata; + alignment: "left" | "right"; +};Based on coding guidelines: "Use types over interfaces for TypeScript".
apps/webapp/app/components/runs/v3/SharedFilters.tsx (2)
277-295: Use type aliases instead of interfaces for TimeFilter types.Prefer
typealiases here to align with the TS style guidelines.♻️ Proposed refactor
-export interface TimeFilterApplyValues { - period?: string; - from?: string; - to?: string; -} +export type TimeFilterApplyValues = { + period?: string; + from?: string; + to?: string; +}; -export interface TimeFilterProps { +export type TimeFilterProps = { defaultPeriod?: string; period?: string; from?: string; to?: string; /** Label name used in the filter display, defaults to "Created" */ labelName?: string; hideLabel?: boolean; applyShortcut?: ShortcutDefinition | undefined; /** Callback when the user applies a time filter selection, receives the applied values */ onValueChange?: (values: TimeFilterApplyValues) => void; -} +};As per coding guidelines, prefer types over interfaces in TS.
864-870: Prefer explicit radix inparseIntfor numeric timestamps.This avoids any ambiguity and makes intent explicit.
🧹 Suggested tweak
- return new Date(parseInt(value)); + return new Date(parseInt(value, 10));apps/webapp/app/v3/services/aiQueryService.server.ts (1)
61-100: Consider guarding against empty time-filter inputs.As-is, the tool accepts
{}and will emit{ period: undefined, from: undefined, to: undefined }. Consider rejecting empty input or normalizing to a sensible default.♻️ Possible guard
execute: async ({ period, from, to }) => { + if (!period && !from && !to) { + return { success: false, message: "Provide period or from/to for time filter." }; + } // Store the time filter so we can include it in the result this.pendingTimeFilter = { period, from, to }; return {apps/webapp/app/components/code/QueryResultsChart.tsx (1)
26-33: Prefer a type alias forQueryResultsChartProps.This repo prefers
typeoverinterface, and this block was just touched.♻️ Proposed refactor
-interface QueryResultsChartProps { +type QueryResultsChartProps = { rows: Record<string, unknown>[]; columns: OutputColumnMetadata[]; config: ChartConfiguration; fullLegend?: boolean; /** Callback when "View all" legend button is clicked */ onViewAllLegendItems?: () => void; -} +};As per coding guidelines, prefer type aliases.
apps/webapp/app/routes/storybook.charts/route.tsx (1)
28-42: Normalize date inputs before slicing.The filter assumes
startDate/endDateexactly match thedataKeystrings. If the range values areDateobjects or include time, filtering becomes a no‑op and zoom/range syncing won’t affect the data. Consider normalizing toYYYY-MM-DD(or comparing byDate) before lookup.♻️ Suggested normalization
-function filterDataByDateRange<T extends Record<string, any>>( - data: T[], - dataKey: string, - startDate: string | undefined, - endDate: string | undefined -): T[] { - if (!startDate || !endDate) return data; +function filterDataByDateRange<T extends Record<string, any>>( + data: T[], + dataKey: string, + startDate: string | Date | undefined, + endDate: string | Date | undefined +): T[] { + const normalize = (value?: string | Date) => + value instanceof Date ? value.toISOString().slice(0, 10) : value; + + const start = normalize(startDate); + const end = normalize(endDate); + if (!start || !end) return data; - const startIndex = data.findIndex((item) => item[dataKey] === startDate); - const endIndex = data.findIndex((item) => item[dataKey] === endDate); + const startIndex = data.findIndex((item) => item[dataKey] === start); + const endIndex = data.findIndex((item) => item[dataKey] === end);
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
apps/webapp/app/components/code/QueryResultsChart.tsxapps/webapp/app/components/code/TSQLResultsTable.tsxapps/webapp/app/components/primitives/AppliedFilter.tsxapps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/routes/storybook.charts/route.tsxapps/webapp/app/v3/services/aiQueryService.server.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/webapp/app/components/primitives/AppliedFilter.tsx
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead
**/*.{ts,tsx}: Always import tasks from@trigger.dev/sdk, never use@trigger.dev/sdk/v3or deprecatedclient.defineJobpattern
Every Trigger.dev task must be exported and have a uniqueidproperty with no timeouts in the run function
Files:
apps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/v3/services/aiQueryService.server.tsapps/webapp/app/routes/storybook.charts/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsxapps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/code/QueryResultsChart.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use zod for validation in packages/core and apps/webapp
Files:
apps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/v3/services/aiQueryService.server.tsapps/webapp/app/routes/storybook.charts/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsxapps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/code/QueryResultsChart.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function declarations instead of default exports
Import from
@trigger.dev/coreusing subpaths only, never import from root
Files:
apps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/v3/services/aiQueryService.server.tsapps/webapp/app/routes/storybook.charts/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsxapps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/code/QueryResultsChart.tsx
apps/webapp/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access all environment variables through the
envexport ofenv.server.tsinstead of directly accessingprocess.envin the Trigger.dev webapp
Files:
apps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/v3/services/aiQueryService.server.tsapps/webapp/app/routes/storybook.charts/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsxapps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/code/QueryResultsChart.tsx
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
apps/webapp/**/*.{ts,tsx}: When importing from@trigger.dev/corein the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webappAccess environment variables via
envexport fromapps/webapp/app/env.server.ts, never useprocess.envdirectly
Files:
apps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/v3/services/aiQueryService.server.tsapps/webapp/app/routes/storybook.charts/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsxapps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/code/QueryResultsChart.tsx
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}
📄 CodeRabbit inference engine (AGENTS.md)
Format code using Prettier before committing
Files:
apps/webapp/app/components/primitives/charts/ChartBar.tsxapps/webapp/app/v3/services/aiQueryService.server.tsapps/webapp/app/routes/storybook.charts/route.tsxapps/webapp/app/components/code/TSQLResultsTable.tsxapps/webapp/app/components/runs/v3/SharedFilters.tsxapps/webapp/app/components/code/QueryResultsChart.tsx
apps/webapp/app/v3/services/**/*.server.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Organize services in the webapp following the pattern
app/v3/services/*/*.server.ts
Files:
apps/webapp/app/v3/services/aiQueryService.server.ts
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)
**/*.ts: When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs
Do not use high-cardinality attributes in OTEL metrics such as UUIDs/IDs (envId, userId, runId, projectId, organizationId), unbounded integers (itemCount, batchSize, retryCount), timestamps (createdAt, startTime), or free-form strings (errorMessage, taskName, queueName)
When exporting OTEL metrics via OTLP to Prometheus, be aware that the exporter automatically adds unit suffixes to metric names (e.g., 'my_duration_ms' becomes 'my_duration_ms_milliseconds', 'my_counter' becomes 'my_counter_total'). Account for these transformations when writing Grafana dashboards or Prometheus queries
Files:
apps/webapp/app/v3/services/aiQueryService.server.ts
🧠 Learnings (2)
📚 Learning: 2025-06-10T09:31:01.040Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 2158
File: internal-packages/clickhouse/src/client/queryBuilder.ts:77-92
Timestamp: 2025-06-10T09:31:01.040Z
Learning: ClickHouse SQL syntax requires GROUP BY clause to come before ORDER BY clause, following standard SQL clause ordering: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT.
Applied to files:
apps/webapp/app/v3/services/aiQueryService.server.ts
📚 Learning: 2026-01-15T11:50:06.067Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.067Z
Learning: Applies to internal-packages/clickhouse/schema/**/*.sql : Follow ClickHouse naming conventions: `raw_` prefix for input tables, `_v1`, `_v2` suffixes for versioning, `_mv_v1` suffix for materialized views
Applied to files:
apps/webapp/app/v3/services/aiQueryService.server.ts
🧬 Code graph analysis (3)
apps/webapp/app/v3/services/aiQueryService.server.ts (2)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/types.ts (1)
AITimeFilter(5-9)internal-packages/tsql/src/query/schema.ts (1)
TableSchema(285-303)
apps/webapp/app/routes/storybook.charts/route.tsx (9)
apps/webapp/app/components/primitives/charts/DateRangeContext.tsx (4)
formatISODate(55-58)formatISODateLong(63-66)useDateRange(110-116)DateRangeProvider(70-108)apps/webapp/app/components/primitives/charts/ChartCompound.tsx (4)
ChartState(72-72)ZoomRange(73-73)Chart(92-98)ChartConfig(72-72)apps/webapp/app/components/primitives/charts/Chart.tsx (2)
ChartState(9-9)ChartConfig(11-20)apps/webapp/app/components/primitives/charts/hooks/useZoomSelection.ts (1)
ZoomRange(3-6)apps/webapp/app/components/primitives/RadioButton.tsx (2)
RadioGroup(93-98)RadioGroupItem(112-165)apps/webapp/app/components/primitives/Paragraph.tsx (1)
Paragraph(88-107)apps/webapp/app/components/primitives/charts/Card.tsx (1)
Card(5-16)apps/webapp/app/components/primitives/SegmentedControl.tsx (1)
SegmentedControl(80-152)apps/webapp/app/components/primitives/charts/BigNumber.tsx (1)
BigNumber(15-46)
apps/webapp/app/components/code/QueryResultsChart.tsx (1)
apps/webapp/app/components/primitives/charts/ChartCompound.tsx (1)
Chart(92-98)
🪛 Biome (2.1.2)
apps/webapp/app/components/code/QueryResultsChart.tsx
[error] 841-842: This hook is being called conditionally, but all hooks must be called in the exact same order in every component render.
Hooks should not be called after an early return.
For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level
(lint/correctness/useHookAtTopLevel)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: typecheck / typecheck
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (30)
apps/webapp/app/components/primitives/charts/ChartBar.tsx (3)
40-55: LGTM with minor type safety note.The type definitions correctly use
typeoverinterfaceper coding guidelines. Theanytype on line 50 forpayloadis acceptable given recharts' loose typing, but could be tightened if a more specific type is available from recharts.
83-99: Event handlers are well-structured.Good use of
useCallbackwith appropriate dependencies. The handlers correctly coordinate zoom and highlight state.
197-238: Bar rendering logic is well-implemented.The stacked bar rendering with per-cell opacity based on highlight state is cleanly implemented. Minor nit: the
indexparameter on line 214 is declared but unused.apps/webapp/app/components/code/TSQLResultsTable.tsx (9)
49-61: LGTM!Constants are well-documented and the
RowDatatype alias properly uses a type (not interface) per coding guidelines.
103-121: DateTime formatting now correctly usestoLocaleString.The previous issue regarding
toLocaleDateStringignoring time options has been properly fixed. The code now usestoLocaleStringwhich correctly includes hour, minute, and second components in the output.
189-212: LGTM!The debounced input implementation is clean and correctly uses
forwardRef. TheonChangedependency in the effect is fine since TanStack Table'ssetFilterValueis stable.
299-329: LGTM!The column width calculation with sampling (first 100 rows) is a good performance optimization. The bounds checking ensures reasonable column sizes.
402-431: Good performance optimization.The
CellValueWrapperpattern that only enables tooltips when hovered is a smart optimization for tables with many cells.
696-756: LGTM!The copyable cell implementation provides good UX with hover-to-reveal copy button and visual feedback on copy success.
758-840: LGTM!Header cell component cleanly handles sorting, filtering, tooltips, and alignment with proper accessibility attributes.
949-954: LGTM!The virtualizer configuration with
overscan: 20provides smooth scrolling without excessive DOM nodes. The estimated row height and scroll element reference are correctly configured.
1134-1177: Virtualization implemented correctly.The tbody uses absolute positioning with
translateYtransforms for efficient rendering of visible rows only. The grid-based layout properly handles variable column widths with resize support.apps/webapp/app/components/runs/v3/SharedFilters.tsx (4)
139-203: Label-awaretimeFiltersflow looks solid.The labelName propagation and render-value wiring is consistent and keeps default handling intact.
206-275: Range render values handle same-day display cleanly.The from/to display logic is clear and keeps the label semantics intact.
297-342: TimeFilter label/controlled wiring looks good.Prop handling is clean and the applied filter label/value rendering remains consistent.
421-489: Controlled vs URL mode application is well separated.The value construction and navigation split reads cleanly and should be easy to extend.
apps/webapp/app/v3/services/aiQueryService.server.ts (8)
10-14: Centralized AITimeFilter type export looks good.Type-only import + re-export keeps compatibility clean.
29-31: Updated AIQueryResult union is clear.The optional
timeFilteron success reads well.
148-148: Nice DRY reuse of the shared setTimeFilter tool.Centralizing the tool builder keeps stream and non-stream behavior aligned.
Also applies to: 214-214
161-166: Accessor for pending time filter is straightforward.Simple and clear.
236-236: IncludingtimeFilterin success result is helpful.Makes downstream usage explicit and avoids extra lookups.
425-441: Prompt guidance for time filtering is clear and consistent.The new rules should steer the model away from
triggered_atfiltering.Also applies to: 518-525
22-24: Thetime_filterevents are actively emitted in the streaming pipeline. When the AI calls thesetTimeFiltertool, the route handler (apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query.ai-generate.tsx, lines 129-136) explicitly detects this tool call and immediately emits atime_filterevent with the filter arguments. The event is then consumed by the UI component (AIQueryInput.tsx, lines 198-200) which applies the time filter via theonTimeFilterChangecallback. The streaming pipeline is working as intended.Likely an incorrect or invalid review comment.
54-55: Remove comment: AIQueryService is instantiated per-request, not reused across concurrent requests.The
AIQueryServiceis created as a local variable within theactionfunction of the route handler (line 87 inquery.ai-generate.tsx). In Remix, theactionfunction is invoked once per HTTP request, so each incoming request receives its own isolated instance. ThependingTimeFilterstate is reset and used entirely within a single request lifecycle, with no possibility of cross-request interference. The concern about concurrent requests overwriting shared state does not apply.apps/webapp/app/components/code/QueryResultsChart.tsx (4)
3-4: LGTM.
699-705: Legend prop wiring looks consistent.Also applies to: 861-898
780-792: Legend label formatter addition looks good.
815-839: Axis prop split reads clean.apps/webapp/app/routes/storybook.charts/route.tsx (2)
267-275: Story wrapper looks solid.Wrapping the dashboard in
DateRangeProviderkeeps the demo’s shared range centralized and easy to reset.
683-767: Chart configs are nicely typed.Using
satisfies ChartConfigkeeps series keys/labels consistent and avoids silent misconfigurations.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
What changed